﻿/*
 * protocolmasterbase.cpp
 *
 *  Created on: 2017年8月27日
 *      Author: work
 */

#include <dm/export.hpp>

#define DM_API_OS_PROTOCOL DM_API_EXPORT

#include <dm/os/protocol/protocolmasterbase.hpp>
#include <dm/os/log/logger.hpp>
#include <dm/datetime.hpp>

namespace dm{
namespace os{
namespace protocol{

static const char* logModule = "CProtocolMasterBase.protocol.os.dm";

CProtocolMasterBase::CProtocolMasterBase():CProtocolBase(){
	log().debug(THISMODULE "创建对象");
}

CProtocolMasterBase::~CProtocolMasterBase(){
	log().debug(THISMODULE "销毁对象");
}

dm::msg::EMsgAck CProtocolMasterBase::taskState2ack( const ETaskState& state ){
	switch( state ){
	case Success:
		return dm::msg::MaSuccess;
	case Fail:
		return dm::msg::MaFail;
	case Permit:
		return dm::msg::MaDeny;
	case Timeout:
		return dm::msg::MaTimeout;
	default:
		return dm::msg::MaFail;
	}
}

CProtocolMasterBase::EAction CProtocolMasterBase::taskEnd_call( const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	if( m_ackCall ){
		dm::os::msg::CMsgInfo msg;
		msg.setAnswer_call(m_callGroup,taskState2ack(m_taskCall) );
		m_msgAgent.sendMsg(msg);
	}

	if( m_taskCall==Timeout ){
		log().info(THISMODULE "任务超时");
		return Action_CloseLink;
	}

	m_taskCall = None;
	log().debug(THISMODULE "任务结束，清除");
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::taskEnd_syncClock( const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	if( m_ackClock ){
		dm::os::msg::CMsgInfo msg;
		msg.setAnswer_syncClock(taskState2ack(m_taskClock) );
		m_msgAgent.sendMsg(msg);
	}

	if( m_taskCall==Timeout )
		return Action_CloseLink;

	m_taskClock = None;
	log().debug(THISMODULE "任务结束，清除");

	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::taskEnd_remoteControl( const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	if( m_ackRmtCtl ){
		dm::os::msg::CMsgInfo msg;
		msg.setAnswer_remoteCtl(m_rmtctlIndex,m_rmtctl,taskState2ack(m_taskRmtCtl) );
		m_msgAgent.sendMsg(msg);
	}

	if( m_taskCall==Timeout ){
		log().debug(THISMODULE "召唤超时，关闭链路");
		return Action_CloseLink;
	}

	log().debug(THISMODULE "远控任务结束，开启消息检测");
	enableRequestMsgCheck(true);
	m_taskRmtCtl = None;

	log().debug(THISMODULE "任务结束，清除");
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::taskEnd_parameters( const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	if( m_ackParas ){
		dm::os::msg::CMsgInfo msg;
		if( m_paraSet )
			msg.setAnswer_set(m_paraData,taskState2ack(m_taskParas) );
		else
			msg.setAnswer_get(m_paraData,taskState2ack(m_taskParas) );
		m_msgAgent.sendMsg(msg);
	}

	if( m_taskCall==Timeout ){
		log().debug(THISMODULE "召唤超时，关闭链路");
		return Action_CloseLink;
	}

	log().debug(THISMODULE "参数任务结束，开启消息检测");
	enableRequestMsgCheck(true);
	m_taskParas = None;
	log().debug(THISMODULE "任务结束，清除");
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::taskEnd_syncData( const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	if( m_ackSync ){
		dm::os::msg::CMsgInfo msg;
		msg.setAnswer_sync(m_syncType,taskState2ack(m_taskSync) );
		m_msgAgent.sendMsg(msg);
	}

	if( m_taskCall==Timeout )
		return Action_CloseLink;

	m_taskSync = None;
	log().debug(THISMODULE "任务结束，清除");
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::taskEnd_reset( const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	if( m_ackReset ){
		dm::os::msg::CMsgInfo msg;
		msg.setAnswer_remoteReset(taskState2ack(m_taskReset) );
		m_msgAgent.sendMsg(msg);
	}

	if( m_taskCall==Timeout )
		return Action_CloseLink;

	m_taskReset = None;
	log().debug(THISMODULE "任务结束，清除");
	return Action_Nothing;
}

/**
 * 是否过滤请求同步时钟命令
 * 默认不过滤。允许对子站设备进行对时
 * @param
 * @return
 */
bool CProtocolMasterBase::filterMsgRequest_syncClock( const dm::os::msg::CMsgInfo& ){
	// 允许对子站同步
	return false;
}

/**
 *  是否过滤请求召唤数据命令
 *  默认不过滤。允许召唤子设备数据
 * @param
 * @return
 */
bool CProtocolMasterBase::filterMsgRequest_call( const dm::os::msg::CMsgInfo& ){
	// 允许召唤子站数据
	return false;
}

/**
 * 是否过滤请求远控命令
 * 根据是否本设备点确定
 * @param msg
 * @return
 */
bool CProtocolMasterBase::filterMsgRequest_rmtCtl( const dm::os::msg::CMsgInfo& msg){
	return !isLocalRemoteCtl(msg.getRemoteCtl().index);
}

/**
 * 是否过滤请求设置参数命令
 * 根据是否本设备点确定
 * @param msg
 * @return
 */
bool CProtocolMasterBase::filterMsgRequest_set( const dm::os::msg::CMsgInfo& msg){
	return !isLocalPara(msg.getParaData().index);
}

/**
 * 是否过滤请求读取参数命令
 * 根据是否本设备点确定
 * @param msg
 * @return
 */
bool CProtocolMasterBase::filterMsgRequest_get( const dm::os::msg::CMsgInfo& msg){
	return !isLocalPara(msg.getPara().index);
}

/**
 * 是否过滤请求更新参数命令
 * 默认过滤。更新参数一般用于子设备发给主站设备。
 * @param msg
 * @return
 */
bool CProtocolMasterBase::filterMsgRequest_update( const dm::os::msg::CMsgInfo&){
	// 不处理参数更新消息
	return true;
}

/**
 * 是否过滤请求同步命令
 * 默认过滤。暂时不支持
 * @param msg
 * @return
 */
bool CProtocolMasterBase::filterMsgRequest_syncData( const dm::os::msg::CMsgInfo& ){
	return true;
}

/**
 * 是否过滤请求复位命令
 * 默认不过滤。一般用于远程复位子设备
 * @param msg
 * @return
 */
bool CProtocolMasterBase::filterMsgRequest_remoteReset( const dm::os::msg::CMsgInfo& ){
	return false;
}

/**
 * 是否过滤应答时钟同步命令
 * 默认过滤。
 * @param msg
 * @return
 */
bool CProtocolMasterBase::filterMsgAnswer_syncClock( const dm::os::msg::CMsgInfo& ){
	return true;
}

/**
 * 是否过滤应答召唤命令
 * 默认过滤。
 * @param msg
 * @return
 */
bool CProtocolMasterBase::filterMsgAnswer_call( const dm::os::msg::CMsgInfo& ){
	return true;
}

/**
 * 是否过滤远控命令
 * 默认过滤。
 * @param msg
 * @return
 */
bool CProtocolMasterBase::filterMsgAnswer_rmtCtl( const dm::os::msg::CMsgInfo& ){
	return true;
}

/**
 * 是否过滤应答参数设置命令
 * 默认过滤。
 * @param msg
 * @return
 */
bool CProtocolMasterBase::filterMsgAnswer_set( const dm::os::msg::CMsgInfo& ){
	return true;
}

/**
 * 是否过滤应答参数读取命令
 * 默认过滤。
 * @param msg
 * @return
 */
bool CProtocolMasterBase::filterMsgAnswer_get( const dm::os::msg::CMsgInfo& ){
	return true;
}

/**
 * 是否过滤应答参数更新命令
 * 根据是否是子设备参数确定
 * @param msg
 * @return
 */
bool CProtocolMasterBase::filterMsgAnswer_update( const dm::os::msg::CMsgInfo& msg ){
	return !isLocalPara(msg.getPara().index);
}

/**
 * 是否过滤应答数据同步命令
 * 默认过滤。暂不支持
 * @param msg
 * @return
 */
bool CProtocolMasterBase::filterMsgAnswer_syncData( const dm::os::msg::CMsgInfo& ){
	return true;
}

/**
 * 是否过滤应答系统复位命令
 * 默认过滤
 * @param msg
 * @return
 */
bool CProtocolMasterBase::filterMsgAnswer_remoteReset( const dm::os::msg::CMsgInfo&){
	return true;
}

/**
 * 处理时钟同步命令
 * 默认设置任务标志。
 * @param msg
 * @param txFrame
 * @return
 */
CProtocolMasterBase::EAction CProtocolMasterBase::onMsgRequest_syncClock( dm::os::msg::CMsgInfo& msg,const ts_t& ts,const rts_t& rts ){
	EAction act = Action_Nothing;

	if( setTask_syncClock(ts,rts) ){
		m_ackClock = (msg.getAck()==dm::msg::MaAck);
		return Action_ReTime;
	}else if( msg.getAck()==dm::msg::MaAck ){
		msg.setAck( dm::msg::MaDeny );
		m_msgAgent.sendMsg(msg);
		log().warnning(THISMODULE "设置时钟同步失败");
	}
	return act;
}

CProtocolMasterBase::EAction CProtocolMasterBase::onMsgRequest_call( dm::os::msg::CMsgInfo& msg,const ts_t& ts,const rts_t& rts ){
	if( setTask_call(ts,rts,msg.getCall()) ){
		m_ackCall = (msg.getAck()==dm::msg::MaAck);
		return Action_ReTime;
	}else if( msg.getAck()==dm::msg::MaAck ){
		msg.setAck( dm::msg::MaDeny );
		m_msgAgent.sendMsg(msg);
		log().warnning(THISMODULE "设置召唤数据失败");
	}
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::onMsgRequest_rmtCtl( dm::os::msg::CMsgInfo& msg,const ts_t& ts,const rts_t& rts ){
	if( setTask_remoteControl(ts,rts,msg.getRemoteCtl()) ){
		m_ackRmtCtl = (msg.getAck()==dm::msg::MaAck);
		log().warnning(THISMODULE "设置远控命令%s。暂停请求消息",dm::CDateTime(msg.getTs()).toString().c_str());
		enableRequestMsgCheck(false);
		return Action_ReTime;
	}else if( msg.getAck()==dm::msg::MaAck ){
		msg.setAck( dm::msg::MaDeny );
		m_msgAgent.sendMsg(msg);
		log().warnning(THISMODULE "设置远控命令失败");
	}
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::onMsgRequest_set( dm::os::msg::CMsgInfo& msg,const ts_t& ts,const rts_t& rts ){
	if( setTask_parasSet(ts,rts,msg.getParaData()) ){
		m_ackParas = (msg.getAck()==dm::msg::MaAck);
		log().warnning(THISMODULE "设置参数写命令%s idx=%d num=%d type=%d。暂停请求消息",dm::CDateTime(msg.getTs()).toString().c_str(),
				m_paraData.index,m_paraData.num,m_paraData.type);
		enableRequestMsgCheck(false);
		return Action_ReTime;
	}else if( msg.getAck()==dm::msg::MaAck ){
		msg.setAck( dm::msg::MaDeny );
		m_msgAgent.sendMsg(msg);
		log().warnning(THISMODULE "设置参数写失败");
	}
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::onMsgRequest_get( dm::os::msg::CMsgInfo& msg,const ts_t& ts,const rts_t& rts ){
	if( setTask_parasGet(ts,rts,msg.getPara()) ){
		m_ackParas = (msg.getAck()==dm::msg::MaAck);
		log().warnning(THISMODULE "设置参数读命令%s。暂停请求消息",dm::CDateTime(msg.getTs()).toString().c_str());
		enableRequestMsgCheck(false);
		return Action_ReTime;
	}else if( msg.getAck()==dm::msg::MaAck ){
		msg.setAck( dm::msg::MaDeny );
		m_msgAgent.sendMsg(msg);
		log().warnning(THISMODULE "设置参数读失败");
	}
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::onMsgRequest_update( dm::os::msg::CMsgInfo& msg,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	if( msg.getAck()==dm::msg::MaAck ){
		msg.setAck( dm::msg::MaDeny );
		m_msgAgent.sendMsg(msg);
		log().warnning(THISMODULE "不支持");
	}
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::onMsgRequest_syncData( dm::os::msg::CMsgInfo& msg,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	if( msg.getAck()==dm::msg::MaAck ){
		msg.setAck( dm::msg::MaDeny );
		m_msgAgent.sendMsg(msg);
		log().warnning(THISMODULE "不支持");
	}
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::onMsgRequest_remoteReset( dm::os::msg::CMsgInfo& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning(THISMODULE "不支持");
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::onMsgAnswer_syncClock( dm::os::msg::CMsgInfo& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning(THISMODULE "不支持");
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::onMsgAnswer_call( dm::os::msg::CMsgInfo& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning(THISMODULE "不支持");
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::onMsgAnswer_rmtCtl( dm::os::msg::CMsgInfo& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning(THISMODULE "不支持");
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::onMsgAnswer_set( dm::os::msg::CMsgInfo& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning(THISMODULE "不支持");
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::onMsgAnswer_get( dm::os::msg::CMsgInfo& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning(THISMODULE "不支持");
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::onMsgAnswer_update( dm::os::msg::CMsgInfo& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning(THISMODULE "不支持");
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::onMsgAnswer_syncData( dm::os::msg::CMsgInfo& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning(THISMODULE "不支持");
	return Action_Nothing;
}

CProtocolMasterBase::EAction CProtocolMasterBase::onMsgAnswer_remoteReset( dm::os::msg::CMsgInfo& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning(THISMODULE "不支持");
	return Action_Nothing;
}

}
}
}
